package cn.itsource.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.itsource.constants.Constants;
import cn.itsource.constants.GlobalExceptionCode;
import cn.itsource.exception.GlobalException;
import cn.itsource.mapper.DriverMapper;
import cn.itsource.pojo.domain.Driver;
import cn.itsource.pojo.domain.DriverAuthMaterial;
import cn.itsource.mapper.DriverAuthMaterialMapper;
import cn.itsource.pojo.domain.DriverMaterialAuthLog;
import cn.itsource.pojo.dto.AuditDto;
import cn.itsource.result.R;
import cn.itsource.romate.api.LoginApi;
import cn.itsource.service.IDriverAuthMaterialService;
import cn.itsource.service.IDriverMaterialAuthLogService;
import cn.itsource.utils.BitStatesUtil;
import cn.itsource.utils.HttpUtils;
import com.alibaba.fastjson.JSON;
import com.aliyun.facebody20191230.Client;
import com.aliyun.facebody20191230.models.CompareFaceRequest;
import com.aliyun.facebody20191230.models.CompareFaceResponse;
import com.aliyun.tea.TeaException;
import com.aliyun.tea.TeaModel;
import com.aliyun.teautil.Common;
import com.aliyun.teautil.models.RuntimeOptions;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.seata.spring.annotation.GlobalTransactional;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * <p>
 * 司机实名资料 服务实现类
 * </p>
 *
 * @author beishan
 * @since 2024-03-25
 */
@Service
@Transactional
public class DriverAuthMaterialServiceImpl extends ServiceImpl<DriverAuthMaterialMapper, DriverAuthMaterial> implements IDriverAuthMaterialService {


    @Autowired
    private DriverMapper driverMapper;

    @Autowired
    private DriverAuthMaterialMapper authMaterialMapper;

    @Autowired
    private IDriverMaterialAuthLogService authLogService;

    @Autowired
    private LoginApi loginApi;

    /**
     * 认证信息 校验 添加到数据库
     *
     * @param material 前端传入的认证信息
     */
    @Override
    public void material(DriverAuthMaterial material) {
        //校验
        // 1、数据库是否存在 该司机登录的认证信息
        long id = StpUtil.getLoginIdAsLong();
        DriverAuthMaterial byId = authMaterialMapper.findById(id);
        Driver driver = driverMapper.selectById(id);
        //2、查看司机的位状态
        if (BitStatesUtil.hasState(driver.getBitState(), BitStatesUtil.OP_REAL_AUTHENTICATIONED)) {
            throw new GlobalException(GlobalExceptionCode.DRIVER_MATERIAL_OVER);
        }
        //3、认证身份证是否正确
//        String host = "https://jmidcardv1.market.alicloudapi.com";
//        String path = "/idcard/validate";
//        String method = "POST";
//        String appcode = "a46a24356cf746039509043370daec5b";
//        Map<String, String> headers = new HashMap<String, String>();
//        //最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
//        headers.put("Authorization", "APPCODE " + appcode);
//
//        Map<String, String> querys = new HashMap<String, String>();
//
//        Map<String, String> bodys = new HashMap<String, String>();
//        bodys.put("idCardNo", material.getIdNumber());
//        bodys.put("name", material.getName());
//
//        try {
//            HttpResponse response = HttpUtils.doPost(host, path, method, headers, querys, bodys);
//            //获取response的body
//            String string = EntityUtils.toString(response.getEntity());
//            //判断response的状态码
//            if (response.getStatusLine().getStatusCode()!= 200) {
//                throw new GlobalException(GlobalExceptionCode.IDNUM_ERROR);
//            }
//            Map<String, Object> map;
//            map = (Map<String, Object>) JSON.parse(string);
//            if (!map.get("code").toString().equals("200")) {
//                throw new GlobalException(GlobalExceptionCode.IDNUM_ERROR);
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//            throw new GlobalException(GlobalExceptionCode.IDNUM_ERROR);
//        }

        Date date = new Date();
        //添加到数据库
        if (byId == null) {
            //添加数据
            material.setId(id);
            material.setDriverId(id);
            material.setRealAuthStatus(Constants.RealAuth.VERIFYING);
            material.setCreateTime(date);
            save(material);
        }else {
            // 审核表 状态为已撤销 重新提交 修改数据库数据
            if(Objects.equals(byId.getRealAuthStatus(), Constants.RealAuth.REVOKE)){
                //修改逻辑删除 状态
                byId.setDeleted(false);
                authMaterialMapper.upd(byId);

                //修改 审核状态
                byId.setRealAuthStatus(Constants.RealAuth.VERIFYING);
                //修改时间
                byId.setUpdateTime(date);
                super.updateById(byId);
            }else {
                throw new GlobalException(GlobalExceptionCode.DRIVER_MATERIAL_NOT_PASS);
            }
        }

        //维护driver表

        driver.setBitState(BitStatesUtil.addState(driver.getBitState(), BitStatesUtil.OP_REAL_AUTHENTICATING));
        driver.setUpdateTime(date);
        driverMapper.updateById(driver);

    }

    /**
     * 回显认证信息
     *
     * @return 认证信息
     */
    @Override
    public DriverAuthMaterial echoMaterial() {
        long id = StpUtil.getLoginIdAsLong();
        DriverAuthMaterial material = super.getById(id);
        if (Objects.equals(material.getRealAuthStatus(), Constants.RealAuth.REVOKE)){
            super.removeById(material.getId());
        }
        return material;
    }

    /**
     * 审核 认证 通过或失败
     *
     * @param auditDto 审核传的相关参数
     */
    @Override
    @GlobalTransactional(name = "driver-audit", rollbackFor = Exception.class)
    public void audit(AuditDto auditDto) {

        DriverAuthMaterial material = super.getById(auditDto.getId());
        //非空校验
        if (material == null) {
            throw new GlobalException(GlobalExceptionCode.PARAM_ERROR);
        }

        //判断状态
        if (Objects.equals(material.getRealAuthStatus(), Constants.RealAuth.APPROVED)) {
            throw new GlobalException(GlobalExceptionCode.DRIVER_MATERIAL_OVER);
        }
        if (Objects.equals(material.getRealAuthStatus(), Constants.RealAuth.VERIFY_FAIL)) {
            throw new GlobalException(GlobalExceptionCode.DRIVER_MATERIAL_NOT_PASS);
        }
        if (Objects.equals(material.getRealAuthStatus(), Constants.RealAuth.REVOKE)) {
            throw new GlobalException(GlobalExceptionCode.DRIVER_MATERIAL_CANCEL);
        }

        Date date = new Date();
        if (auditDto.getApprove()) {//认证成功
            //认证状态
            material.setRealAuthStatus(Constants.RealAuth.APPROVED);
            //修改时间
            material.setUpdateTime(date);
            //审核时间
            material.setAuditTime(date);
            //司机id
            material.setDriverId(auditDto.getId());
            //管理员id
            long id = StpUtil.getLoginIdAsLong();
            material.setAuditUserId(id);
            //审核备注
            material.setAuditRemark(auditDto.getRemark());
            super.updateById(material);

            //维护driver表的位状态
            Driver driver = driverMapper.selectById(auditDto.getId());
            //删除审核中的位状态
            driver.setBitState(BitStatesUtil.removeState(driver.getBitState(), BitStatesUtil.OP_REAL_AUTHENTICATING));
            //添加认证成功的位状态
            driver.setBitState(BitStatesUtil.addState(driver.getBitState(), BitStatesUtil.OP_REAL_AUTHENTICATIONED));
            driverMapper.updateById(driver);

            //远程维护login表 TODO
            R r = loginApi.updLogin(auditDto.getId(), material.getName());
            if (!r.isSuccess()) {
                throw new GlobalException("审核有误");
            }

        } else { //认证失败
            //认证状态
            material.setRealAuthStatus(Constants.RealAuth.VERIFY_FAIL);
            //修改时间
            material.setUpdateTime(date);
            //审核时间
            material.setAuditTime(date);
            //管理员id
            long id = StpUtil.getLoginIdAsLong();
            material.setAuditUserId(id);
            //审核备注
            material.setAuditRemark(auditDto.getRemark());
            super.updateById(material);

            //维护driver表的位状态
            Driver driver = driverMapper.selectById(auditDto.getId());
            //删除审核中的位状态
            driver.setBitState(BitStatesUtil.removeState(driver.getBitState(), BitStatesUtil.OP_REAL_AUTHENTICATING));
            driverMapper.updateById(driver);

        }

        //维护日志表
        DriverMaterialAuthLog authLog = new DriverMaterialAuthLog();
        //审核状态
        authLog.setRealAuthStatus(auditDto.getApprove() ? Constants.RealAuth.APPROVED : Constants.RealAuth.VERIFY_FAIL);
        //审核备注
        authLog.setAuditRemark(auditDto.getRemark());
        //审核时间
        authLog.setAuditTime(date);
        //审核人id
        authLog.setAuditUserId(StpUtil.getLoginIdAsLong());
        //创建时间
        authLog.setCreateTime(date);
        //认证表id
        authLog.setAuthMaterialId(material.getId());
        authLogService.save(authLog);
    }

    /**
     * 审核撤销 更改审核表的状态、driver表的位状态、添加日志
     *
     * @param auditDto 审核传的相关参数
     */
    @Override
    public void cancel(AuditDto auditDto) {
        DriverAuthMaterial material = super.getById(auditDto.getId());
        Driver driver = driverMapper.selectById(auditDto.getId());
        //非空校验
        if (material == null) {
            throw new GlobalException(GlobalExceptionCode.PARAM_ERROR);
        }
        //判断状态
        //认证中
        if (Objects.equals(material.getRealAuthStatus(), Constants.RealAuth.VERIFYING)) {
            throw new GlobalException(GlobalExceptionCode.DRIVER_MATERIAL_EXPIRE);
        }
        //已经撤销
        if (Objects.equals(material.getRealAuthStatus(), Constants.RealAuth.REVOKE)) {
            throw new GlobalException(GlobalExceptionCode.DRIVER_MATERIAL_CANCEL);
        }

        Date date = new Date();
        //修改审核表的状态
        material.setRealAuthStatus(Constants.RealAuth.REVOKE);
        //修改时间
        material.setUpdateTime(date);
        //审核时间
        material.setAuditTime(date);
        //管理员id
        long id = StpUtil.getLoginIdAsLong();
        material.setAuditUserId(id);
        //审核备注
        material.setAuditRemark(auditDto.getRemark());
        super.updateById(material);

        //维护driver表的位状态
        //删除审核通过的位状态
        if (BitStatesUtil.hasState(driver.getBitState(), BitStatesUtil.OP_REAL_AUTHENTICATIONED)) {
            driver.setBitState(BitStatesUtil.removeState(driver.getBitState(), BitStatesUtil.OP_REAL_AUTHENTICATIONED));
        }
        driverMapper.updateById(driver);

        //维护日志表
        //维护日志表
        DriverMaterialAuthLog authLog = new DriverMaterialAuthLog();
        //审核状态
        authLog.setRealAuthStatus(Constants.RealAuth.REVOKE);
        //审核备注
        authLog.setAuditRemark(auditDto.getRemark());
        //审核时间
        authLog.setAuditTime(date);
        //审核人id
        authLog.setAuditUserId(StpUtil.getLoginIdAsLong());
        //创建时间
        authLog.setCreateTime(date);
        //认证表id
        authLog.setAuthMaterialId(material.getId());
        authLogService.save(authLog);

    }

    /**
     * 人脸识别
     * @throws Exception
     */
    @Override
    public void face()  {

        // 创建AccessKey ID和AccessKey Secret，请参考https://help.aliyun.com/document_detail/175144.html
        // 如果您使用的是RAM用户的AccessKey，还需要为子账号授予权限AliyunVIAPIFullAccess，请参考https://help.aliyun.com/document_detail/145025.html
        // 从环境变量读取配置的AccessKey ID和AccessKey Secret。运行代码示例前必须先配置环境变量。
        String accessKeyId = "LTAI5tP6Q3yxDewgd2eSHat1";
        String accessKeySecret = "eaMhDC19HoeVfWZYPidgbmEnc2SJTi";
        Client client = null;
        try {
            client = createClient(accessKeyId, accessKeySecret);
        } catch (Exception e) {
            e.printStackTrace();
            throw new GlobalException("系统错误");
        }
        CompareFaceRequest compareFaceRequest = new CompareFaceRequest()
                .setImageURLA("http://viapi-test.oss-cn-shanghai.aliyuncs.com/viapi-3.0domepic/facebody/CompareFace/CompareFace-right1.png")
                .setImageURLB("http://viapi-test.oss-cn-shanghai.aliyuncs.com/viapi-3.0domepic/facebody/CompareFace/CompareFace-left1.png");
        RuntimeOptions runtime = new RuntimeOptions();
        try {
            // 复制代码运行请自行打印 API 的返回值
            CompareFaceResponse compareFaceResponse = client.compareFaceWithOptions(compareFaceRequest, runtime);
            // 获取整体结果
            System.out.println(Common.toJSONString(TeaModel.buildMap(compareFaceResponse)));
        } catch (Exception e) {
        e.printStackTrace();
        }
    }


    // 这里只是以ocr为例，其他能力请使用相应类目的包下面的Client类
    public static com.aliyun.facebody20191230.Client createClient(String accessKeyId, String accessKeySecret) throws Exception {
        /*
          初始化配置对象com.aliyun.teaopenapi.models.Config
          Config对象存放 AccessKeyId、AccessKeySecret、endpoint等配置
         */
        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
                .setAccessKeyId(accessKeyId)
                .setAccessKeySecret(accessKeySecret);
        // 访问的域名
        config.endpoint = "facebody.cn-shanghai.aliyuncs.com";
        return new com.aliyun.facebody20191230.Client(config);
    }
}
